home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.5)
-
- __revision__ = '$Id: streamsasl.py 678 2008-08-08 11:22:14Z jajcus $'
- __docformat__ = 'restructuredtext en'
- import base64
- import logging
- from pyxmpp.jid import JID
- from pyxmpp import sasl
- from pyxmpp.exceptions import StreamAuthenticationError, SASLNotAvailable, SASLMechanismNotAvailable, SASLAuthenticationFailed
- SASL_NS = 'urn:ietf:params:xml:ns:xmpp-sasl'
-
- class StreamSASLMixIn(sasl.PasswordManager):
-
- def __init__(self, sasl_mechanisms = ()):
- sasl.PasswordManager.__init__(self)
- if sasl_mechanisms:
- self.sasl_mechanisms = sasl_mechanisms
- else:
- self.sasl_mechanisms = []
- self._StreamSASLMixIn__logger = logging.getLogger('pyxmpp.StreamSASLMixIn')
-
-
- def _reset_sasl(self):
- self.peer_sasl_mechanisms = None
- self.authenticator = None
-
-
- def _make_stream_sasl_features(self, features):
- if self.sasl_mechanisms and not (self.authenticated):
- ml = features.newChild(None, 'mechanisms', None)
- ns = ml.newNs(SASL_NS, None)
- ml.setNs(ns)
- for m in self.sasl_mechanisms:
- if m in sasl.all_mechanisms:
- ml.newTextChild(None, 'mechanism', m)
- continue
-
-
- return features
-
-
- def _handle_sasl_features(self):
- ctxt = self.doc_in.xpathNewContext()
- ctxt.setContextNode(self.features)
- ctxt.xpathRegisterNs('sasl', SASL_NS)
-
- try:
- sasl_mechanisms_n = ctxt.xpathEval('sasl:mechanisms/sasl:mechanism')
- finally:
- ctxt.xpathFreeContext()
-
- if sasl_mechanisms_n:
- self._StreamSASLMixIn__logger.debug('SASL support found')
- self.peer_sasl_mechanisms = []
- for n in sasl_mechanisms_n:
- self.peer_sasl_mechanisms.append(n.getContent())
-
-
-
-
- def _process_node_sasl(self, xmlnode):
- ns_uri = xmlnode.ns().getContent()
- if ns_uri == SASL_NS:
- self._process_sasl_node(xmlnode)
- return True
-
- return False
-
-
- def _process_sasl_node(self, xmlnode):
- if self.initiator:
- if not self.authenticator:
- self._StreamSASLMixIn__logger.debug('Unexpected SASL response: %r' % xmlnode.serialize())
- ret = False
- elif xmlnode.name == 'challenge':
- ret = self._process_sasl_challenge(xmlnode.getContent())
- elif xmlnode.name == 'success':
- ret = self._process_sasl_success(xmlnode.getContent())
- elif xmlnode.name == 'failure':
- ret = self._process_sasl_failure(xmlnode)
- else:
- self._StreamSASLMixIn__logger.debug('Unexpected SASL node: %r' % xmlnode.serialize())
- ret = False
- elif xmlnode.name == 'auth':
- mechanism = xmlnode.prop('mechanism')
- ret = self._process_sasl_auth(mechanism, xmlnode.getContent())
-
- if xmlnode.name == 'response':
- ret = self._process_sasl_response(xmlnode.getContent())
-
- if xmlnode.name == 'abort':
- ret = self._process_sasl_abort()
- else:
- self._StreamSASLMixIn__logger.debug('Unexpected SASL node: %r' % xmlnode.serialize())
- ret = False
- return ret
-
-
- def _process_sasl_auth(self, mechanism, content):
- if self.authenticator:
- self._StreamSASLMixIn__logger.debug('Authentication already started')
- return False
-
- self.auth_method_used = 'sasl:' + mechanism
- self.authenticator = sasl.server_authenticator_factory(mechanism, self)
- r = self.authenticator.start(base64.decodestring(content))
- if isinstance(r, sasl.Success):
- el_name = 'success'
- content = r.base64()
- elif isinstance(r, sasl.Challenge):
- el_name = 'challenge'
- content = r.base64()
- else:
- el_name = 'failure'
- content = None
- root = self.doc_out.getRootElement()
- xmlnode = root.newChild(None, el_name, None)
- ns = xmlnode.newNs(SASL_NS, None)
- xmlnode.setNs(ns)
- if content:
- xmlnode.setContent(content)
-
- if isinstance(r, sasl.Failure):
- xmlnode.newChild(None, r.reason, None)
-
- self._write_raw(xmlnode.serialize(encoding = 'UTF-8'))
- xmlnode.unlinkNode()
- xmlnode.freeNode()
- if isinstance(r, sasl.Success):
- if r.authzid:
- self.peer = JID(r.authzid)
- else:
- self.peer = JID(r.username, self.me.domain)
- self.peer_authenticated = 1
- self.state_change('authenticated', self.peer)
- self._post_auth()
-
- if isinstance(r, sasl.Failure):
- raise SASLAuthenticationFailed, 'SASL authentication failed'
-
- return True
-
-
- def _process_sasl_challenge(self, content):
- if not self.authenticator:
- self._StreamSASLMixIn__logger.debug('Unexpected SASL challenge')
- return False
-
- r = self.authenticator.challenge(base64.decodestring(content))
- if isinstance(r, sasl.Response):
- el_name = 'response'
- content = r.base64()
- else:
- el_name = 'abort'
- content = None
- root = self.doc_out.getRootElement()
- xmlnode = root.newChild(None, el_name, None)
- ns = xmlnode.newNs(SASL_NS, None)
- xmlnode.setNs(ns)
- if content:
- xmlnode.setContent(content)
-
- self._write_raw(xmlnode.serialize(encoding = 'UTF-8'))
- xmlnode.unlinkNode()
- xmlnode.freeNode()
- if isinstance(r, sasl.Failure):
- raise SASLAuthenticationFailed, 'SASL authentication failed'
-
- return True
-
-
- def _process_sasl_response(self, content):
- if not self.authenticator:
- self._StreamSASLMixIn__logger.debug('Unexpected SASL response')
- return 0
-
- r = self.authenticator.response(base64.decodestring(content))
- if isinstance(r, sasl.Success):
- el_name = 'success'
- content = r.base64()
- elif isinstance(r, sasl.Challenge):
- el_name = 'challenge'
- content = r.base64()
- else:
- el_name = 'failure'
- content = None
- root = self.doc_out.getRootElement()
- xmlnode = root.newChild(None, el_name, None)
- ns = xmlnode.newNs(SASL_NS, None)
- xmlnode.setNs(ns)
- if content:
- xmlnode.setContent(content)
-
- if isinstance(r, sasl.Failure):
- xmlnode.newChild(None, r.reason, None)
-
- self._write_raw(xmlnode.serialize(encoding = 'UTF-8'))
- xmlnode.unlinkNode()
- xmlnode.freeNode()
- if isinstance(r, sasl.Success):
- authzid = r.authzid
- if authzid:
- self.peer = JID(r.authzid)
- else:
- self.peer = JID(r.username, self.me.domain)
- self.peer_authenticated = 1
- self._restart_stream()
- self.state_change('authenticated', self.peer)
- self._post_auth()
-
- if isinstance(r, sasl.Failure):
- raise SASLAuthenticationFailed, 'SASL authentication failed'
-
- return 1
-
-
- def _process_sasl_success(self, content):
- if not self.authenticator:
- self._StreamSASLMixIn__logger.debug('Unexpected SASL response')
- return False
-
- r = self.authenticator.finish(base64.decodestring(content))
- if isinstance(r, sasl.Success):
- self._StreamSASLMixIn__logger.debug('SASL authentication succeeded')
- if r.authzid:
- self.me = JID(r.authzid)
- else:
- self.me = self.me
- self.authenticated = 1
- self._restart_stream()
- self.state_change('authenticated', self.me)
- self._post_auth()
- else:
- self._StreamSASLMixIn__logger.debug('SASL authentication failed')
- raise SASLAuthenticationFailed, 'Additional success data procesing failed'
- return True
-
-
- def _process_sasl_failure(self, xmlnode):
- if not self.authenticator:
- self._StreamSASLMixIn__logger.debug('Unexpected SASL response')
- return False
-
- self._StreamSASLMixIn__logger.debug('SASL authentication failed: %r' % (xmlnode.serialize(),))
- raise SASLAuthenticationFailed, 'SASL authentication failed'
-
-
- def _process_sasl_abort(self):
- if not self.authenticator:
- self._StreamSASLMixIn__logger.debug('Unexpected SASL response')
- return False
-
- self.authenticator = None
- self._StreamSASLMixIn__logger.debug('SASL authentication aborted')
- return True
-
-
- def _sasl_authenticate(self, username, authzid, mechanism = None):
- if not self.initiator:
- raise SASLAuthenticationFailed, 'Only initiating entity start SASL authentication'
-
- while not self.features:
- self._StreamSASLMixIn__logger.debug('Waiting for features')
- self._read()
- if not self.peer_sasl_mechanisms:
- raise SASLNotAvailable, "Peer doesn't support SASL"
-
- if not mechanism:
- mechanism = None
- for m in self.sasl_mechanisms:
- if m in self.peer_sasl_mechanisms:
- mechanism = m
- break
- continue
-
- if not mechanism:
- raise SASLMechanismNotAvailable, "Peer doesn't support any of our SASL mechanisms"
-
- self._StreamSASLMixIn__logger.debug('Our mechanism: %r' % (mechanism,))
- elif mechanism not in self.peer_sasl_mechanisms:
- raise SASLMechanismNotAvailable, '%s is not available' % (mechanism,)
-
- self.auth_method_used = 'sasl:' + mechanism
- self.authenticator = sasl.client_authenticator_factory(mechanism, self)
- initial_response = self.authenticator.start(username, authzid)
- if not isinstance(initial_response, sasl.Response):
- raise SASLAuthenticationFailed, 'SASL initiation failed'
-
- root = self.doc_out.getRootElement()
- xmlnode = root.newChild(None, 'auth', None)
- ns = xmlnode.newNs(SASL_NS, None)
- xmlnode.setNs(ns)
- xmlnode.setProp('mechanism', mechanism)
- if initial_response.data:
- xmlnode.setContent(initial_response.base64())
-
- self._write_raw(xmlnode.serialize(encoding = 'UTF-8'))
- xmlnode.unlinkNode()
- xmlnode.freeNode()
-
-
-